/*----------------------------------------------------------------------------
 | Copyright (c) 2009 Matthew B. Brophy (matt@brophy.org).  
 | Liscense: MIT License (http://www.opensource.org/licenses/mit-license.php)
 |
 | $Id: event.js 37 2010-04-05 18:25:24Z matt@brophy.org $
 -----------------------------------------------------------------------------*/

if (typeof org == "undefined" || 
    org == null) { org = {}; }
if (typeof org.brophy == "undefined" || 
    org.brophy == null) { org.brophy = {}; }
if (typeof org.brophy.js == "undefined" || 
    org.brophy.js == null) { org.brophy.js = {}; }

/** 
 * @namespace 
 * @description Event namespace in the org.brophy.js JavaScript library 
 * @requires    This library requires the <a href="http://www.mochikit.com">
 *              MochiKit</a> JavaScript library 
 *              (version 1.4+).
 */
org.brophy.js.event = {};

/**
 * Get the element that fired the event 'e'
 * @param   e   
 *          The event being fired.  This function is smart enough to
 *          determine whether this is a standard DOM event, or a MochiKit
 *          event object.
 *
 * @return  The element that fired the event
 * @type    HTMLElement
 */
org.brophy.js.event.getElement = function(e)
{
  var elem;
  if (!e) 
    e = window.event;
  if (e.target && org.brophy.js.util.typeOf(e.target) !== 'function')
    elem = e.target;
  else if (e.srcElement) 
    elem = e.srcElement;
  else if(e.src && org.brophy.js.util.typeOf(e.src) === 'function')
    return e.src(); // MochiKit Events

  // defeat Safari bug
  if (elem.nodeType == 3) 
    elem = targ.parentNode;

  return elem;
}

/**
 * Get the coordinates of the mouse pointer for the mouse event 'e' relative
 * to the top left hand corner of the document.
 * @param   e   
 *          The mouse event being fired 
 *          (onmousedown,onmousemove,onmouseup,onmouseover,onmouseout)
 *
 * @return  An object containing the absolute x and y coordinates of the mouse 
 *          cursor, relative to the top left corner of the document.  Note that
 *          this includes any scrolling by the user.
 * @type    Object {'x': [int],'y': [int]}
 */
org.brophy.js.event.getAbsoluteMouseCoords = function(e) 
{
  var posx = 0;
  var posy = 0;
  if (!e) var e = window.event;
  if (e.pageX || e.pageY)   
  {
    posx = e.pageX;
    posy = e.pageY;
  }
  else if (e.clientX || e.clientY)
  {
    posx = e.clientX + document.body.scrollLeft
     + document.documentElement.scrollLeft;
    posy = e.clientY + document.body.scrollTop
     + document.documentElement.scrollTop;
  }

  return {'x':posx,'y':posy};
}

/**
 * Get the coordinates of the mouse pointer for the mouse event 'e' relative
 * to the current viewport
 * @param   e   
 *          The mouse event being fired 
 *          (onmousedown,onmousemove,onmouseup,onmouseover,onmouseout)
 *
 * @return  An object containing the relative x and y coordinates of the mouse 
 *          cursor, relative to the top left corner of the viewport.  
 * @type    Object {'x': [int],'y': [int]}
 */
org.brophy.js.event.getRelativeMouseCoords = function(e) 
{
  var posx = 0;
  var posy = 0;
  if (!e) var e = window.event;
  if (e.pageX || e.pageY)   
  {
    posx = e.pageX - org.brophy.js.util.getScrollX();
    posy = e.pageY - org.brophy.js.util.getScrollY();
  }
  else if (e.clientX || e.clientY)
  {
    posx = e.clientX;
    posy = e.clientY;
  }

  return {'x':posx,'y':posy};
}

/**
 * Get the key code of the event 'e'
 * @param   e
 *          The event being fired
 * @return  The keycode for the event, or -1 if there is no keycode 
 *          associated with the event
 * @type    integer
 */
org.brophy.js.event.getKeyCode = function(e)
{
  if(!e) 
    { e = window.event; }

  if(e.which) 
    return e.which;   // Standards compliant browsers
  else if(e.keyCode) 
    return e.keyCode; // IE browsers
  else if(e.key && org.brophy.js.util.typeOf(e.key) === 'function')
    return e.key().code; // MochiKit Events
  else return -1;
}

/**
 * Check if the event 'e' was related the the key given by the keyCode 'keyCode'.
 * This can be used for onkeydown, onkeypress, or onkeyup.
 * @param  e
 *         The event being fired
 * @param  keyCode
 *         The integer keycode value for the key we are looking for
 * @return TRUE if the event key was equal to keyCode, FALSE otherwise.
 */
org.brophy.js.event.isKey = function(e,keyCode)
{
  return org.brophy.js.event.getKeyCode(e) === keyCode;
}

/**
 * Check if the event 'e' was on the Enter key
 * @param  e
 *         The event being fired
 * @return TRUE if the event key was equal to the Enter key, FALSE otherwise.
 */
org.brophy.js.event.isEnter = function(e)
{
  return org.brophy.js.event.isKey(e,org.brophy.js.constant.KEY_ENTER);
}

/**
 * Check if the event 'e' was on the Escape key
 * @param  e
 *         The event being fired
 * @return TRUE if the event key was equal to the Escape key, FALSE otherwise.
 */
org.brophy.js.event.isEscape = function(e)
{
  return org.brophy.js.event.isKey(e,org.brophy.js.constant.KEY_ESCAPE);
}

/**
 * Cancel the event 'e'
 * @param  e
 *         The event to cancel
 * @return none
 */
org.brophy.js.event.cancel = function(e)
{
  e.cancelBubble = true;
  if( e.stopPropagation &&
      org.brophy.js.util.typeOf(e.stopPropagation === 'function') )
    { e.stopPropagation(); }
}

org.brophy.js.event.setHighlightRowAndColumnOnEvent = function(td, eventName, styleObj)
{
  if(isUndefinedOrNull(eventName)) { throw "'eventName' must be specified"; }
  else if(isUndefinedOrNull(styleObj)) { styleObj = {}; }
  var outerFunc = function(e)
  {
    var td = e.src();
    if(td.tagName !== "TD") { td = findAncestorByTagName(td, "TD"); }
    if(td == null) { throw "No containing <TD> found"; }
    return org.brophy.js.util.setRowAndColumnStyle(td, styleObj);
  }
  connect(td, eventName, outerFunc);
}

